#include "../tracer.h"
#include <chrono>
#include <cmath>
#include <iostream>
#include <string>
#include <thread>
#include <vector>

// 模拟一个计算密集型任务
void compute_task(int iterations) {
  TRACE_SCOPE("compute_task");

  volatile double result = 0.0;
  for (int i = 0; i < iterations; ++i) {
    TRACE_SCOPE("compute_iteration");

    // 一些计算工作
    for (int j = 0; j < 1000000; ++j) {
      result += sin(j * 0.0001) * cos(j * 0.0001);
    }

    // 记录一个即时事件
    if (i % 5 == 0) {
      TRACE_INSTANT("iteration_milestone");
    }

    // 短暂休眠模拟 I/O 等待
    if (i % 3 == 0) {
      std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
  }
}

// 模拟一个 I/O 任务
void io_task(int operations) {
  TRACE_SCOPE("io_task");

  for (int i = 0; i < operations; ++i) {
    TRACE_SCOPE("io_operation");

    // 模拟 I/O 操作的延迟
    std::this_thread::sleep_for(std::chrono::milliseconds(50));

    // 模拟处理 I/O 结果的一些计算
    volatile double result = 0.0;
    for (int j = 0; j < 100000; ++j) {
      result += sin(j * 0.001);
    }
  }
}

// 多线程工作函数
void worker_thread(int id, int compute_iterations, int io_operations) {
  TRACE_SCOPE("worker_thread");

  // 设置线程名称
  char thread_name[32];
  snprintf(thread_name, sizeof(thread_name), "Worker-%d", id);
  pthread_setname_np(pthread_self(), thread_name);

  // 执行一些计算任务
  compute_task(compute_iterations);

  // 执行一些 I/O 任务
  io_task(io_operations);
}

int main() {
  TRACE_SCOPE("main");

  std::cout << "Tracer example program starting..." << std::endl;

  // 创建多个工作线程
  std::vector<std::thread> threads;
  const int num_threads = 4;

  for (int i = 0; i < num_threads; ++i) {
    // 每个线程执行不同工作量的任务
    int compute_iterations = 10 + i;
    int io_operations = 5 + (i % 3);

    threads.emplace_back(worker_thread, i, compute_iterations, io_operations);

    // 稍微错开线程启动时间
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
  }

  // 主线程也做一些工作
  {
    TRACE_SCOPE("main_processing");

    // 主线程执行一些操作
    std::cout << "Main thread processing..." << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    // 添加一些即时事件
    TRACE_INSTANT("main_work_checkpoint");
  }

  // 等待所有线程完成
  for (auto &t : threads) {
    t.join();
  }

  // 保存跟踪结果到文件
  std::cout
      << "\nAll threads completed.\nSaving trace to 'trace_result.json'..."
      << std::endl;
  TRACE_SAVE("trace_result.json");

  std::cout << "Example completed. Open 'trace_result.json' in "
               "chrome://tracing to view results."
            << std::endl;
  return 0;
}
